package com.baozheyangken.ai_learn.service.serviceImpl;

import com.baozheyangken.ai_learn.mapper.DifficultyLevelMapper;
import com.baozheyangken.ai_learn.mapper.KnowledgeMapper;
import com.baozheyangken.ai_learn.pojo.dto.KnowledgeDTO;
import com.baozheyangken.ai_learn.pojo.dto.KnowledgePageQueryDTO;
import com.baozheyangken.ai_learn.pojo.entity.Course;
import com.baozheyangken.ai_learn.pojo.entity.DifficultyLevel;
import com.baozheyangken.ai_learn.pojo.entity.Knowledge;
import com.baozheyangken.ai_learn.pojo.result.PageResult;
import com.baozheyangken.ai_learn.pojo.result.Result;
import com.baozheyangken.ai_learn.pojo.vo.KnowledgeInsertVO;
import com.baozheyangken.ai_learn.pojo.vo.KnowledgeUpdateVO;
import com.baozheyangken.ai_learn.service.KnowledgeService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mysql.cj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class KnowledgeServiceImpl implements KnowledgeService {

    @Autowired
    private KnowledgeMapper knowledgeMapper;

    @Autowired
    private DifficultyLevelMapper difficultyLevelMapper;

    @Override
    public Result knowledgeInsert(KnowledgeInsertVO knowledgeVO) {
        //先判断课程id和难度等级id是否存在
        //Todo 查询课程暂时写在difficultyMapper中
        Course course = difficultyLevelMapper
                .getCourseById(knowledgeVO.getCourseId());
        if (course == null)
            return Result.error("课程不存在");

        DifficultyLevel difficultyLevel = difficultyLevelMapper
                .getDifficultyLevelById(knowledgeVO.getDifficultyId());
        if (difficultyLevel == null)
            return Result.error("难度等级不存在");

        Result result = new Result();

        Knowledge knowledge = new Knowledge();
        BeanUtils.copyProperties(knowledgeVO, knowledge);
        knowledge.setCreatedAt(LocalDateTime.now());
        knowledge.setUpdatedAt(LocalDateTime.now());
        knowledgeMapper.insertKnowledge(knowledge);

        log.info("添加成功：{}", knowledge);
        result.setMsg("知识点添加成功");
        result.setCode(1);
        return result;
    }

    @Override
    public PageResult knowledgeQuery(KnowledgePageQueryDTO knowledgePageQueryDTO) {
        PageHelper.startPage(knowledgePageQueryDTO.getPage(), knowledgePageQueryDTO.getPageSize());
        Page<Knowledge> page = knowledgeMapper.pageQuery(knowledgePageQueryDTO);

        long total = page.getTotal();
        List<Knowledge> list = page.getResult();

        List<KnowledgeDTO> knowledgeDTOS = new ArrayList<>();
        for (Knowledge knowledge : list) {
            Course course = difficultyLevelMapper.getCourseById(knowledge.getCourseId());
            DifficultyLevel dif = difficultyLevelMapper.getDifficultyLevelById(knowledge.getDifficultyId());
            Integer count = knowledgeMapper.getQuestionCountByKnowledgeId(knowledge.getId());
            KnowledgeDTO knowledgeDTO = KnowledgeDTO.builder()
                    .id(knowledge.getId())
                    .title(knowledge.getTitle())
                    .description(knowledge.getDescription())
                    .courseName(course.getCourseName())
                    .mainModule(knowledge.getMainModule())
                    .subModule(knowledge.getSubModule())
                    .questionCount(count)
                    .difficulty(dif.getLevelName())
                    .build();
            knowledgeDTOS.add(knowledgeDTO);
        }

        log.info("分页查询：total:{},record:{}", total, knowledgeDTOS);
        return new PageResult(total, knowledgeDTOS);
    }

    @Override
    public Result knowledgeUpdate(KnowledgeUpdateVO knowledgeVO) {
        Knowledge knowledge = knowledgeMapper.getKnowledgeById(knowledgeVO.getId());
        if (knowledge == null)
            return Result.error("知识点不存在");

        Knowledge curKnowledge = new Knowledge();
        BeanUtils.copyProperties(knowledgeVO, curKnowledge);
        curKnowledge.setUpdatedAt(LocalDateTime.now());
        knowledgeMapper.updateKnowledge(curKnowledge);

        Result result = new Result();
        result.setMsg("知识点更新成功");
        result.setCode(1);
        return result;
    }

    @Override
    @Transactional
    public Result knowledgeDelete(Long knowledgeId) {
        //查询所有要删除的questionId
        List<Integer> questionIds = knowledgeMapper.getQuestionIds(knowledgeId);
        log.info("所有要删除的questionId:{}", questionIds);

        // 按照正确的删除顺序执行：先删除关联表，再删除问题，最后删除知识点
        knowledgeMapper.deleteQuestionKnowledgeByKnowledgeId(knowledgeId);
        if (!questionIds.isEmpty())
            knowledgeMapper.deleteQuestionByKnowledgeId(questionIds);
        knowledgeMapper.deleteKnowledgeById(knowledgeId);

        Result result = new Result();
        result.setMsg("知识点删除成功");
        result.setCode(1);
        return result;
    }

    /**
     * 导出知识点导入模板
     *
     * @return
     * @throws IOException
     */
    @Override
    public Resource exportTemplate() throws IOException {
        // 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("知识点导入模板");

        // 设置表头样式
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);

        StringBuilder sb = getDifficultyLevels();
        log.info("难度等级：{}", sb);

        // 创建表头行
        Row headerRow = sheet.createRow(0);
        String[] headers = {"标题", "详细内容", "一级模块", "二级模块", sb.toString()};

        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
            // 设置列宽
            sheet.setColumnWidth(i, 15 * 256);
        }

        // 添加示例数据行（可选）
        Row exampleRow = sheet.createRow(1);
        exampleRow.createCell(0).setCellValue("函数极限");
        exampleRow.createCell(1).setCellValue("介绍函数极限的概念及其应用");
        exampleRow.createCell(2).setCellValue("微积分基础");
        exampleRow.createCell(3).setCellValue("极限理论");
        exampleRow.createCell(4).setCellValue("1");

        // 写入到字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();

        return new ByteArrayResource(outputStream.toByteArray());
    }

    /**
     * 导入知识点
     *
     * @param file
     * @param courseId
     * @return
     */
    @Override
    public Result<String> importKnowledge(MultipartFile file, Long courseId) {
        //判断课程是否存在
        Course course = difficultyLevelMapper.getCourseById(courseId);
        if (course == null)
            return Result.error("课程id不存在");

        List<DifficultyLevel> difficultyLevels = difficultyLevelMapper.getDifficultyIds();
        List<Long> difficultyIds = difficultyLevels.stream().
                map(DifficultyLevel::getId).toList();
        //1.先获取workbook
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = new XSSFWorkbook(inputStream)) {
            Sheet sheet = workbook.getSheetAt(0);
            int successCount = 0, failCount = 0;

            //2.遍历每一行
            for (int i = 2; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                try {
                    Knowledge knowledge = parseRowToKnowledge(row, courseId);
                    validateKnowledge(knowledge, difficultyIds);
                    knowledgeMapper.insertKnowledge(knowledge);
                    successCount++;
                } catch (Exception e) {
                    log.warn("第{}行数据导入失败：{}", i + 1, e.getMessage());
                    failCount++;
                }
            }

            //3.返回汇总结果
            String msg = String.format("导入完成，成功%d条，失败%d条", successCount, failCount);
            return Result.success(msg);

        } catch (IOException e) {
            log.error("导入异常", e);
            return Result.error("导入失败：" + e.getMessage());
        }
    }

    /**
     * 导出知识点
     *
     * @param courseId
     * @return
     */
    @Override
    public Resource exportExcel(Long courseId) throws Exception {
        Course course = difficultyLevelMapper.getCourseById(courseId);
        List<Knowledge> knowledgeList = validateKnowledge(courseId, course);
        //创建工作簿
        Workbook workbook = new XSSFWorkbook();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        Sheet sheet = workbook.createSheet("导出" + course.getCourseName() + "的知识点");

        //设置表头样式
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);

        //创建表头行
        Row headerRow = sheet.createRow(0);
        String[] headers = {"id", "标题", "详情", "所属课程", "一级模块", "二级模块", "难度等级", "创建时间", "修改时间"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
            sheet.setColumnWidth(i, 15 * 256);
        }

        //创建日期格式化样式
        CellStyle dateStyle = workbook.createCellStyle();
        CreationHelper createHelper = workbook.getCreationHelper();
        dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));

        //添加数据
        for (int i = 0; i < knowledgeList.size(); i++) {
            Row row = sheet.createRow(i + 1);
            Knowledge knowledge = knowledgeList.get(i);
            row.createCell(0).setCellValue(knowledge.getId());
            row.createCell(1).setCellValue(knowledge.getTitle());
            row.createCell(2).setCellValue(knowledge.getDescription());
            row.createCell(3).setCellValue(course.getCourseName());
            row.createCell(4).setCellValue(knowledge.getMainModule());
            row.createCell(5).setCellValue(knowledge.getSubModule());
            row.createCell(6).setCellValue(knowledge.getDifficultyId());

            // 格式化日期
            Cell dateCell = row.createCell(7);
            dateCell.setCellValue(knowledge.getCreatedAt());
            dateCell.setCellStyle(dateStyle);
            Cell updateCell = row.createCell(8);
            updateCell.setCellValue(knowledge.getUpdatedAt());
            updateCell.setCellStyle(dateStyle);
        }
        sheet.autoSizeColumn(7);
        sheet.autoSizeColumn(8);

        //写入到字节数组
        workbook.write(outputStream);
        workbook.close();
        return new ByteArrayResource(outputStream.toByteArray());
    }

    //将每一行封装为实体类
    public Knowledge parseRowToKnowledge(Row row, Long courseId) throws Exception {
        Knowledge knowledge = new Knowledge();
        knowledge.setTitle(getCellStringValue(row.getCell(0)));
        knowledge.setDescription(getCellStringValue(row.getCell(1)));
        knowledge.setMainModule(getCellStringValue(row.getCell(2)));
        knowledge.setSubModule(getCellStringValue(row.getCell(3)));

        //解析难度等级
        String difficultyLevel = getCellStringValue(row.getCell(4));
        if (StringUtils.isStrictlyNumeric(difficultyLevel)) {
            knowledge.setDifficultyId(Long.parseLong(difficultyLevel));
        } else
            throw new Exception("难度等级必须为数字ID");

        knowledge.setCourseId(courseId);
        knowledge.setCreatedAt(LocalDateTime.now());
        knowledge.setUpdatedAt(LocalDateTime.now());
        return knowledge;
    }

    //将单元格内容统一转换为字符串
    public String getCellStringValue(Cell cell) {
        if (cell == null) return "";
        return switch (cell.getCellType()) {
            case STRING -> cell.getStringCellValue().trim();
            case NUMERIC -> String.valueOf((int) cell.getNumericCellValue());
            default -> "";
        };
    }

    //校验知识点
    public void validateKnowledge(Knowledge knowledge, List<Long> difficultyIds) throws Exception {
        if (knowledge.getTitle().isEmpty())
            throw new Exception("知识点标题不能为空");
        if (!difficultyIds.contains(knowledge.getDifficultyId()))
            throw new Exception("难度等级id不存在");
    }

    //校验导出知识点并获取该courseId下的所有知识点
    public List<Knowledge> validateKnowledge(Long courseId, Course course) throws Exception {
        if (course == null)
            throw new Exception("课程不存在");
        List<Knowledge> knowledgeList = knowledgeMapper.getKnowledgeByCourseId(courseId);
        if (knowledgeList.isEmpty())
            throw new Exception("该课程不存在知识点");
        return knowledgeList;
    }

    //获取难度等级
    public StringBuilder getDifficultyLevels() {
        //todo 获取难度等级
        List<DifficultyLevel> getDifficultyIds = difficultyLevelMapper.getDifficultyIds();
        StringBuilder sb = new StringBuilder();
        sb.append("难度等级(");
        getDifficultyIds.forEach(difficultyLevel -> sb
                .append(difficultyLevel.getLevelName())
                .append("-")
                .append(difficultyLevel.getId())
                .append(",")
        );
        sb.deleteCharAt(sb.length() - 1).append(")");
        return sb;
    }
}
